/* @(#)FmsNodeActivity.java
** 
** Copyright (C) 2012 by Steven D. Stamps
**
**             Trademarks & Copyrights
** Flywheel Management Science(TM), Flywheel Management Model(TM),
** Flywheel Story Editor(TM) and FlywheelMS(TM) are exclusive trademarks
** of Steven D. Stamps and may only be used freely for the purpose of
** identifying the unforked version of this software.  Subsequent forks
** may not use these trademarks.  All other rights are reserved.
**
** DecKanGL (Decorated Kanban Glyph Language) and TribKn (Tribal Knowledge)
** are also exclusive trademarks of Steven D. Stamps.  These may be used
** freely within the unforked FlywheelMS application and documentation.
** All other rights are reserved.
**
** gConGUI (game Controller Graphical User Interface) is an exclusive
** trademark of Steven D. Stamps.  This trademark may be used freely
** within the unforked FlywheelMS application and documentation.
** All other rights are reserved.
**
** Trademark information is available at
** <http://www.flywheelms.com/trademarks>
**
** Flywheel Management Science(TM) is a copyrighted body of management
** metaphors, governance processes, and leadership techniques that is
** owned by Steven D. Stamps.  These copyrighted materials may be freely
** used, without alteration, by the community (users and developers)
** surrounding this GPL3-licensed software.  Additional copyright
** information is available at <http://www.flywheelms.org/copyrights>
**
**              GPL3 Software License
** This program is free software: you can use it, redistribute it and/or
** modify it under the terms of the GNU General Public License, version 3,
** as published by the Free Software Foundation. This program is distributed
** in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
** even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
** PURPOSE.  See the GNU General Public License for more details. You should
** have received a copy of the GNU General Public License, in a file named
** COPYING, along with this program.  If you cannot find your copy, see
** <http://www.gnu.org/licenses/gpl-3.0.html>.
*/

package com.flywheelms.library.fms.activity;

import java.util.ArrayList;

import org.json.JSONException;
import org.json.JSONObject;

import android.os.Bundle;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;

import com.flywheelms.library.FmsLibraryActivity;
import com.flywheelms.library.R;
import com.flywheelms.library.fmm.node.impl.enumerator.FmmNodeDictionary;
import com.flywheelms.library.fmm.node.interfaces.horizontal.FmmNode;
import com.flywheelms.library.fms.helper.FmsActivityHelper;
import com.flywheelms.library.fms.miscellaneous.FmsContext;
import com.flywheelms.library.fms.view.FmsAnalysisView;
import com.flywheelms.library.fms.view.FmsCommitmentsView;
import com.flywheelms.library.fms.view.FmsCommunityView;
import com.flywheelms.library.fms.view.FmsDecKanGlView;
import com.flywheelms.library.fms.view.FmsDocumentSectionAuditView;
import com.flywheelms.library.fms.view.FmsDocumentSectionHistoryView;
import com.flywheelms.library.fms.view.FmsDocumentSectionNotesView;
import com.flywheelms.library.fms.view.FmsDocumentSectionStoryView;
import com.flywheelms.library.fms.view.FmsGovernanceView;
import com.flywheelms.library.fms.view.FmsStrategicPlanningView;
import com.flywheelms.library.fms.view.FmsWorkBreakdownView;
import com.flywheelms.library.fms.view.FmsWorkPlanningView;
import com.flywheelms.library.fse.model.FseDocument;
import com.flywheelms.library.gcg.helper.GcgButtonHelper;
import com.flywheelms.library.gcg.helper.GcgButtonMenu;
import com.flywheelms.library.gcg.viewflipper.GcgViewFlipper;
import com.flywheelms.library.gcg.widget.GcgSpinnableMenu;

public abstract class FmsNodeActivity extends FmsLibraryActivity {
	
	protected ArrayList<String> navigationNodeIdStringList;
	protected String initialNodeIdStringToDisplay;
	private ArrayList<String> peerNodeIdList = new ArrayList<String>();
	protected FmmNodeDictionary fmmNodeDefinition;
	protected String navigationParentNodeIdString;
	protected FmmNodeDictionary nodeListParentFmmNodeDefinition;
	protected Button navigateFirstButton;
	protected Button navigateLeftButton;
	protected Button navigateRightButton;
	protected Button navigateLastButton;
	protected EditText headlineEditText;
	protected TextView navigationListPosition;
	protected LinearLayout fmsContextLayout;
	protected ImageView fmsContextPerspectiveImageView;
	protected FmsContext fmsContext;
	private GcgSpinnableMenu leftSpinnableMenu;
	private LinearLayout leftMenuLayout;
	private FrameLayout viewPagerFrame;
	private GcgViewFlipper tribKnViewFlipper;
	protected FmsDecKanGlView fmsDecKanGlView;
	protected FmsGovernanceView fmsGovernanceView;
	protected FmsCommitmentsView fmsCommitmentsView;
	protected FmsCommunityView fmsCommunityView;
	protected GcgButtonMenu tribKnLeftButtonMenu;
	private GcgViewFlipper documentViewFlipper;
	protected FmsDocumentSectionStoryView fmsDocumentSectionStoryView;
	protected FmsDocumentSectionNotesView fmsDocumentSectionNotesView;
	protected FmsDocumentSectionHistoryView fmsDocumentSectionHistoryView;
	protected FmsDocumentSectionAuditView fmsDocumentSectionAuditView;
	protected GcgButtonMenu documentLeftButtonMenu;
	private GcgViewFlipper contextViewFlipper;
	protected FmsStrategicPlanningView fmsStrategicPlanningView;
	protected FmsWorkBreakdownView fmsWorkBreakdownView;
	protected FmsWorkPlanningView fmsWorkPlanningView;
	protected FmsAnalysisView fmsAnalysisView;
	protected GcgButtonMenu contextLeftButtonMenu;
	private float lastXposition;
	protected FseDocument fseDocument;

	public FmsNodeActivity(FmmNodeDictionary anFmmNodeDictionaryEntry, String aHelpContextUrlString) {
		super(aHelpContextUrlString);
		this.fmmNodeDefinition = anFmmNodeDictionaryEntry;
	}
	
	@Override
	public void onCreate(Bundle savedInstanceState) {
	    super.onCreate(savedInstanceState);
		Bundle theExtrasBundle = getIntent().getExtras();
		if (theExtrasBundle != null) {
			this.navigationNodeIdStringList = theExtrasBundle.getStringArrayList(FmsActivityHelper.bundle_key__NAVIGATION_NODE_ID_LIST);
			this.initialNodeIdStringToDisplay = theExtrasBundle.getString(FmsActivityHelper.bundle_key__INITIAL_NODE_TO_DISPLAY);
			this.navigationParentNodeIdString = theExtrasBundle.getString(FmsActivityHelper.bundle_key__NAVIGATION_PARENT_NODE_ID);
			String theClassName = theExtrasBundle.getString(FmsActivityHelper.bundle_key__NAVIGATION_PARENT_CLASS_NAME);
			this.nodeListParentFmmNodeDefinition = FmmNodeDictionary.getEntryForNodeClassName(theClassName);
			try {
				this.fmsContext = new FmsContext(new JSONObject(theExtrasBundle.getString(FmsActivityHelper.bundle_key__FMS_CONTEXT)));
			} catch (JSONException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		initializeGui();
		displayFmsContext();
		displayFmmNode(this.initialNodeIdStringToDisplay);
		updateNavigationControls();
	}

	private void displayFmsContext() {
		this.fmsContextPerspectiveImageView.setBackgroundResource(this.fmsContext.getPerspectiveIconDrawableResourceId());
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem aMenuItem) {
		switch (aMenuItem.getItemId()) {
		case android.R.id.home:
			finish();
			return true;
		default:
			break;
		}
		return super.onOptionsItemSelected(aMenuItem);
	}

	private void initializeGui() {
		setContentView(R.layout.fms_node_activity);
		initializeFmsContextPanel();
		initializeNavigationPanel();
		initLeftSpinnableMenu();
		initializeNodeViewFlippers();
		getActionBar().setDisplayHomeAsUpEnabled(true);
	}
	
	@Override
	public boolean onTouchEvent(MotionEvent aTouchevent) {
		switch (aTouchevent.getAction()) {
		case MotionEvent.ACTION_DOWN:
			FmsNodeActivity.this.lastXposition = aTouchevent.getX();
			break;
		case MotionEvent.ACTION_UP:
			float theCurrentX = aTouchevent.getX();
			GcgViewFlipper theViewFlipper = (GcgViewFlipper) FmsNodeActivity.this.leftSpinnableMenu.getViewBodyArray().get(
					FmsNodeActivity.this.leftSpinnableMenu.getActiveMenuIndex()); 
			if (FmsNodeActivity.this.lastXposition < theCurrentX) {
				if (theViewFlipper.getDisplayedChild()==0) break;
				theViewFlipper.setInAnimation(
						theViewFlipper.getFlipInFromLeftAnimation());
				theViewFlipper.setOutAnimation(
						theViewFlipper.getFlipOutToRightAnimation());
				theViewFlipper.showNext();
			}
			if (FmsNodeActivity.this.lastXposition > theCurrentX) {
				if (theViewFlipper.getDisplayedChild()==1) break;
				theViewFlipper.setInAnimation(
						theViewFlipper.getFlipInFromRightAnimation());
				theViewFlipper.setOutAnimation(
						theViewFlipper.getFlipOutToLeftAnimation());
				theViewFlipper.showPrevious();
			}
			break;
		}
		return false;
	}

	private void initializeFmsContextPanel() {
		this.fmsContextLayout = (LinearLayout) findViewById(R.id.fms_context__layout);
		this.fmsContextPerspectiveImageView = (ImageView) findViewById(R.id.fms_context__perspective_image);
	}

	private void initializeNavigationPanel() {
		this.navigateFirstButton = (Button) findViewById(R.id.navigate_beginning_button);
		this.navigateFirstButton.setOnClickListener(new Button.OnClickListener() {
			
			@Override
			public void onClick(View v) {
				navigateToBeginning();
			}
		});
		this.navigateLeftButton = (Button) findViewById(R.id.navigate_left_button);
		this.navigateLeftButton.setOnClickListener(new Button.OnClickListener() {
			
			@Override
			public void onClick(View v) {
				navigateLeft();
			}
		});
		this.navigateRightButton = (Button) findViewById(R.id.navigate_right_button);
		this.navigateRightButton.setOnClickListener(new Button.OnClickListener() {
			
			@Override
			public void onClick(View v) {
				navigateRight();
			}
		});
		this.navigateLastButton = (Button) findViewById(R.id.navigate_end_button);
		this.navigateLastButton.setOnClickListener(new Button.OnClickListener() {
			
			@Override
			public void onClick(View v) {
				navigateToEnd();
			}
		});
		this.headlineEditText = (EditText) findViewById(R.id.headline);
		this.navigationListPosition = (TextView) findViewById(R.id.navigation_list_position);
	}
    
	private void initializeNodeViewFlippers() {
		this.viewPagerFrame = (FrameLayout) findViewById(R.id.view_pager_frame);
		this.tribKnViewFlipper = (GcgViewFlipper) findViewById(R.id.tribkn__view_flipper);
		this.tribKnViewFlipper.setViewFlipListener(this.tribKnLeftButtonMenu);
		this.leftSpinnableMenu.getViewBodyArray().add(this.tribKnViewFlipper);
		this.fmsDecKanGlView = (FmsDecKanGlView) findViewById(R.id.fms_deckangl_view);
		this.fmsDecKanGlView.initialize(this, 0, 0);
		this.fmsGovernanceView = (FmsGovernanceView) findViewById(R.id.fms_governance_view);
		this.fmsGovernanceView.initialize(this, 0, 1);
		this.fmsCommitmentsView = (FmsCommitmentsView) findViewById(R.id.fms_commitments_view);
		this.fmsCommitmentsView.initialize(this, 0, 2);
		this.fmsCommunityView = (FmsCommunityView) findViewById(R.id.fms_community_view);
		this.fmsCommunityView.initialize(this, 0, 3);
		this.documentViewFlipper = (GcgViewFlipper) findViewById(R.id.document_section__view_flipper);
		this.documentViewFlipper.setViewFlipListener(this.documentLeftButtonMenu);
		this.leftSpinnableMenu.getViewBodyArray().add(this.documentViewFlipper);
		this.fmsDocumentSectionStoryView = (FmsDocumentSectionStoryView) findViewById(R.id.fms_document_section__story_view);
		this.fmsDocumentSectionNotesView = (FmsDocumentSectionNotesView) findViewById(R.id.fms_document_section__notes_view);
		this.fmsDocumentSectionHistoryView = (FmsDocumentSectionHistoryView) findViewById(R.id.fms_document_section__history_view);
		this.fmsDocumentSectionAuditView = (FmsDocumentSectionAuditView) findViewById(R.id.fms_document_section__audit_view);
		this.contextViewFlipper = (GcgViewFlipper) findViewById(R.id.context__view_flipper);
		this.contextViewFlipper.setViewFlipListener(this.contextLeftButtonMenu);
		this.leftSpinnableMenu.getViewBodyArray().add(this.contextViewFlipper);
		this.fmsStrategicPlanningView = (FmsStrategicPlanningView) findViewById(R.id.fms_strategic_planning_view);
		this.fmsWorkBreakdownView = (FmsWorkBreakdownView) findViewById(R.id.fms_work_breakdown_view);
		this.fmsWorkPlanningView = (FmsWorkPlanningView) findViewById(R.id.fms_work_planning_view);
		this.fmsAnalysisView = (FmsAnalysisView) findViewById(R.id.fms_analysis_view);
	}

	///////////////////////////

	public FmmNodeDictionary getFmmNodeDefinition() {
		if(this.fmmNodeDefinition == null) {
			this.fmmNodeDefinition = FmmNodeDictionary.getEntryForClass(getNodeClass());
		}
		return this.fmmNodeDefinition;
	}

	protected void updateNavigationControls() {
		this.navigationListPosition.setText(
				this.navigationNodeIdStringList.indexOf(getDisplayedFmmNodeIdString()) + 1 +
					"  of " + this.navigationNodeIdStringList.size() );
		int theCurrentIndex = this.navigationNodeIdStringList.indexOf(getDisplayedFmmNodeIdString());
		if(theCurrentIndex == 0) {
			this.navigateFirstButton.setEnabled(false);
			this.navigateLeftButton.setEnabled(false);
			this.navigateRightButton.setEnabled(true);
			this.navigateLastButton.setEnabled(true);
		} else if(theCurrentIndex == this.navigationNodeIdStringList.size() - 1) {
			this.navigateFirstButton.setEnabled(true);
			this.navigateLeftButton.setEnabled(true);
			this.navigateRightButton.setEnabled(false);
			this.navigateLastButton.setEnabled(false);
		} else {
			this.navigateFirstButton.setEnabled(true);
			this.navigateLeftButton.setEnabled(true);
			this.navigateRightButton.setEnabled(true);
			this.navigateLastButton.setEnabled(true);
		}
	}

	private void navigateToBeginning() {
		int theCurrentIndex = this.navigationNodeIdStringList.indexOf(getDisplayedFmmNodeIdString());
		if(theCurrentIndex == 0) {
			return;
		}
		displayFmmNode(this.navigationNodeIdStringList.get(0));
		updateNavigationControls();
	}

	private void navigateLeft() {
		int theCurrentIndex = this.navigationNodeIdStringList.indexOf(getDisplayedFmmNodeIdString());
		if(theCurrentIndex == 0) {
			return;
		}
		displayFmmNode(this.navigationNodeIdStringList.get(theCurrentIndex - 1));
		updateNavigationControls();
	}

	private void navigateRight() {
		int theCurrentIndex = this.navigationNodeIdStringList.indexOf(getDisplayedFmmNodeIdString());
		if(theCurrentIndex == this.navigationNodeIdStringList.size() - 1) {
			return;
		}
		displayFmmNode(this.navigationNodeIdStringList.get(theCurrentIndex + 1));
		updateNavigationControls();
	}

	private void navigateToEnd() {
		int theCurrentIndex = this.navigationNodeIdStringList.indexOf(getDisplayedFmmNodeIdString());
		if(theCurrentIndex == this.navigationNodeIdStringList.size() - 1) {
			return;
		}
		displayFmmNode(this.navigationNodeIdStringList.get(this.navigationNodeIdStringList.size() - 1));
		updateNavigationControls();
	}

	protected abstract Class<? extends FmmNode> getNodeClass();
	
	protected abstract void displayFmmNode(String aNodeIdString);
	
	protected abstract String getDisplayedFmmNodeIdString();

	private void initLeftSpinnableMenu() {
		int[] theMenuBodyResourceIdArray = {
				R.id.tribkn_menu__body,
				R.id.document_menu__body,
				R.id.context_menu__body };
		this.leftMenuLayout = (LinearLayout) findViewById(R.id.fms_node_activity__left_menu_layout);
		this.leftSpinnableMenu = new GcgSpinnableMenu(
				this,
				this.leftMenuLayout,
				GcgSpinnableMenu.DECORATORS_LEFT,
				R.id.left_menu__heading_spinner,
				R.array.fms_node_activity__left_menu__heading_array,
				theMenuBodyResourceIdArray );
		initTribKnMenu();
		initDocumentMenu();
		initContextMenu();
	}

	private void initTribKnMenu() {
		ArrayList<Button> theButtonList = new ArrayList<Button>();
		theButtonList.add((Button) this.leftMenuLayout.findViewById(R.id.tribkn_button__deckangl));
		theButtonList.add((Button) this.leftMenuLayout.findViewById(R.id.tribkn_button__governance));
		theButtonList.add((Button) this.leftMenuLayout.findViewById(R.id.tribkn_button__commitments));
		theButtonList.add((Button) this.leftMenuLayout.findViewById(R.id.tribkn_button__community));
    	this.tribKnLeftButtonMenu = new GcgButtonMenu(
    			theButtonList,
    			0,
    			GcgButtonHelper.color_resource_DEFAULT_BUTTON_SELECTED,
    			GcgButtonHelper.color_resource_DEFAULT_BUTTON_NOT_SELECTED);
    	this.tribKnLeftButtonMenu.initializeMenuState();
	}

	private void initDocumentMenu() {
		ArrayList<Button> theButtonList = new ArrayList<Button>();
		theButtonList.add((Button) this.leftMenuLayout.findViewById(R.id.document_button__story));
		theButtonList.add((Button) this.leftMenuLayout.findViewById(R.id.document_button__notes));
		theButtonList.add((Button) this.leftMenuLayout.findViewById(R.id.document_button__history));
		theButtonList.add((Button) this.leftMenuLayout.findViewById(R.id.document_button__contributors));
    	this.documentLeftButtonMenu = new GcgButtonMenu(
    			theButtonList,
    			0,
    			GcgButtonHelper.color_resource_DEFAULT_BUTTON_SELECTED,
    			GcgButtonHelper.color_resource_DEFAULT_BUTTON_NOT_SELECTED);
    	this.documentLeftButtonMenu.initializeMenuState();
	}

	private void initContextMenu() {
		ArrayList<Button> theButtonList = new ArrayList<Button>();
		theButtonList.add((Button) this.leftMenuLayout.findViewById(R.id.context_button__strategic_planning));
		theButtonList.add((Button) this.leftMenuLayout.findViewById(R.id.context_button__work_breakdown));
		theButtonList.add((Button) this.leftMenuLayout.findViewById(R.id.context_button__work_planning));
		theButtonList.add((Button) this.leftMenuLayout.findViewById(R.id.context_button__analysis));
    	this.contextLeftButtonMenu = new GcgButtonMenu(
    			theButtonList,
    			0,
    			GcgButtonHelper.color_resource_DEFAULT_BUTTON_SELECTED,
    			GcgButtonHelper.color_resource_DEFAULT_BUTTON_NOT_SELECTED);
    	this.contextLeftButtonMenu.initializeMenuState();
	}

	// for FDK
	public View getLeftMenuLayout() {
		return this.leftMenuLayout;
	}
	
	public void onClickTribKnDecKanGl(View v) {
		this.tribKnLeftButtonMenu.onClickMenuButton(this.tribKnViewFlipper, 0);
	}
	
	public void onClickTribKnGovernance(View v) {
		this.tribKnLeftButtonMenu.onClickMenuButton(this.tribKnViewFlipper, 1);
	}
	
	public void onClickTribKnCommitments(View v) {
		this.tribKnLeftButtonMenu.onClickMenuButton(this.tribKnViewFlipper, 2);
	}
	
	public void onClickTribKnCommunity(View v) {
		this.tribKnLeftButtonMenu.onClickMenuButton(this.tribKnViewFlipper, 3);
	}
	
	public void onClickDocumentStory(View v) {
		this.documentLeftButtonMenu.onClickMenuButton(this.documentViewFlipper, 0);
	}
	
	public void onClickStoryNotes(View v) {
		this.documentLeftButtonMenu.onClickMenuButton(this.documentViewFlipper, 1);
	}
	
	public void onClickStoryHistory(View v) {
		this.documentLeftButtonMenu.onClickMenuButton(this.documentViewFlipper, 2);
	}
	
	public void onClickStoryContributors(View v) {
		this.documentLeftButtonMenu.onClickMenuButton(this.documentViewFlipper, 3);
	}
	
	public void onClickContextStrategicPlanning(View v) {
		this.contextLeftButtonMenu.onClickMenuButton(this.contextViewFlipper, 0);
	}
	
	public void onClickContextWorkBreakdown(View v) {
		this.contextLeftButtonMenu.onClickMenuButton(this.contextViewFlipper, 1);
	}
	
	public void onClickContextWorkPlanning(View v) {
		this.contextLeftButtonMenu.onClickMenuButton(this.contextViewFlipper, 2);
	}
	
	public void onClickContextAnalysis(View v) {
		this.contextLeftButtonMenu.onClickMenuButton(this.contextViewFlipper, 3);
	}

}
